
package com.taotao.tools.core.bean;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ConverterUtils {

    /**
     * 转换集合
     *
     * @param srcList     数据来源
     * @param targetClass 转换成的类型
     * @param <T>
     * @param <Q>
     * @return
     * @throws Exception
     */
    public static <T, Q> List<T> converList(Collection<Q> srcList, final Class<T> targetClass) throws Exception {
        return converList(srcList, targetClass, null);
    }


    /**
     * 转换集合
     *
     * @param srcList     数据来源
     * @param targetClass 转换成的类型
     * @param converter   特殊属性转化器
     * @param <T>
     * @param <Q>
     * @return
     * @throws Exception
     */
    public static <T, Q> List<T> converList(Collection<Q> srcList, final Class<T> targetClass, PropertiesConverter converter) {
        if (isEmpty(srcList) || null == targetClass) {
            throw new IllegalArgumentException();
        }

        List<T> targetList = new ArrayList<>(srcList.size());
        for (Q q : srcList) {
            T targetObj = converObject(q, targetClass, converter);
            targetList.add(targetObj);
        }

        return targetList;
    }


    /**
     * 转换对象
     *
     * @param srcObj      数据来源
     * @param targetClass 转换成的类型
     * @param <T>
     * @param <Q>
     * @return
     * @throws Exception
     */
    public static <T, Q> T converObject(Q srcObj, Class<T> targetClass) {
        return converObject(srcObj, targetClass, null);
    }


    /**
     * 转换对象
     *
     * @param srcObj      数据来源
     * @param targetClass 转换成的类型
     * @param converter   特殊属性转化器
     * @param <T>
     * @param <Q>
     * @return
     * @throws Exception
     */
    public static <T, Q> T converObject(Q srcObj, Class<T> targetClass, PropertiesConverter converter) {
        Preconditions.checkArgument(null != srcObj);
        Preconditions.checkArgument(null != targetClass);

        T targetObj = JSON.parseObject(JSON.toJSONString(srcObj), targetClass);
        if (null != converter) {
            converter.convertProperties(srcObj, targetObj);
        }
        return targetObj;
    }


    public static boolean isEmpty(Collection<?> collection) {
        return (collection == null || collection.isEmpty());
    }


    /**
     * 属性转化
     */
    public interface PropertiesConverter<T, Q> {

        /**
         * 转化特殊属性
         *
         * @param srcObj
         * @param targetObj
         */
        void convertProperties(Q srcObj, T targetObj);
    }
}
